<template>
  <el-dialog
    :title="dialogTitle"
    v-model="dialogVisible"
    width="500px"
    :close-on-click-modal="false"
    destroy-on-close
    @open="handleOpen"
    :before-close="handleClose"
  >
    <el-divider class="zdy-divider" />
    <el-form ref="roleFormRef" :model="roleForm" :rules="rules" style="margin-top: 20px" label-width="110px">
      <el-form-item label="角色名称：" prop="roleName">
        <el-input :disabled="isReadonly" v-model="roleForm.roleName" placeholder="请输入角色名称" clearable></el-input>
      </el-form-item>

      <el-form-item label="角色描述：" prop="description">
        <el-input
          :disabled="isReadonly"
          v-model="roleForm.description"
          placeholder="请输入角色描述"
          clearable
        ></el-input>
      </el-form-item>

      <el-form-item label="所具备权限：" prop="menuId">
        <div class="permissionList">
          <div class="permissionList-item1">
            <el-input-tag v-model="permissionsTags" readonly clearable placeholder="请选择权限" />
          </div>
        </div>
      </el-form-item>
      <el-form-item label="">
        <div class="permissionList">
          <div class="permissionList-item2">
            <div>
              <span>共 {{ permissionsTags?.length }} 个权限</span>
            </div>
            <div>
              <el-button
                type="primary"
                style="margin-left: 10px"
                :disabled="isEmpty(treeMenuData)"
                @click="openPermissionSelector('menu')"
              >
                {{ isReadonly ? "详情" : "选择权限" }}
              </el-button>
            </div>
          </div>
        </div>
      </el-form-item>
      <el-form-item label="数据权限：" prop="cockpitIds">
        <div class="permissionList">
          <div class="permissionList-item1">
            <el-input-tag v-model="cockpitPermissions" readonly clearable placeholder="请选择数据权限" />
          </div>
        </div>
      </el-form-item>
      <el-form-item label="">
        <div class="permissionList">
          <div class="permissionList-item2">
            <div>
              <span>共 {{ cockpitPermissions?.length }} 个数据权限</span>
            </div>
            <div>
              <el-button
                type="primary"
                style="margin-left: 10px"
                :disabled="isEmpty(treeCockpitData)"
                @click="openPermissionSelector('cockpit')"
              >
                {{ isReadonly ? "详情" : "选择数据权限" }}
              </el-button>
            </div>
          </div>
        </div>
      </el-form-item>
    </el-form>
    <el-divider class="zdy-divider" />
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClose">关闭</el-button>
      <el-button type="primary" @click="handleSubmit" v-if="!isReadonly">保存</el-button>
    </span>
  </el-dialog>
  <addRoleTreeDialog
    :title="treeDialogTitle"
    :data="treeData"
    :isReadonly="isReadonly"
    :checkList="treeCheckList"
    v-model:visible="treeDialogVisible"
    @treeActive="treeBackListWay"
  />
</template>

<script setup>
import { ref, computed, reactive } from "vue"
import { ElMessage } from "element-plus"
import { saveRole, getMenuByRoleId } from "@/api/roleUser/index.js"
import { getMenuTreeList } from "@/api/menu/index.js"
import addRoleTreeDialog from "./addRoleTreeDialog.vue"
import { getTree } from "../../../api/roleUser"
import { isEmpty } from "lodash-es"
// 定义 emits
const emit = defineEmits(["saveBack", "update:visible"])

// 定义 props
const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  rowData: {
    type: Object,
    default: {}
  },
  isReadonly: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: "新增角色"
  }
})

const dialogTitle = computed(() => props.title)

const dialogVisible = computed({
  get: () => props.visible,
  set: (val) => {
    // 修改为正确的变量名
    emit("update:visible", val)
  }
})
const treeDialogVisible = ref(false)
const treeDialogTitle = ref("")
const treeDialogType = ref("") // menu：角色权限；cockpit：数据权限
const treeMenuData = ref([])
const treeMenuCheckList = ref([])
const treeCockpitData = ref([])
const treeCockpitCheckList = ref([])

const treeData = computed(() =>
  treeDialogType.value === "menu" ? treeMenuData.value : treeDialogType.value === "cockpit" ? treeCockpitData.value : []
)
const treeCheckList = computed(() =>
  treeDialogType.value === "menu"
    ? treeMenuCheckList.value
    : treeDialogType.value === "cockpit"
      ? treeCockpitCheckList.value
      : []
)

const roleForm = reactive({
  id: undefined,
  roleName: "",
  description: "",
  menuId: [],
  cockpitIds: []
})

const isReadonly = computed(() => props.isReadonly)

const permissionsTags = ref([])
const cockpitPermissions = ref([])
const rules = ref({
  roleName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
  menuId: [{ required: true, message: "请选择权限", trigger: "change" }],
  cockpitIds: [{ required: true, message: "请选择数据权限", trigger: "change" }]
})

const openPermissionSelector = (type) => {
  treeDialogType.value = type
  if (type === "menu") {
    treeDialogTitle.value = props.isReadonly ? "角色权限详情" : "角色权限选择"
  } else treeDialogTitle.value = type === props.isReadonly ? "数据权限详情" : "数据权限选择"
  treeDialogVisible.value = true
}
const roleFormRef = ref(null) // 定义表单引用

const handleSubmit = () => {
  if (!roleFormRef.value) return
  // 调用表单的 validate 方法进行验证
  roleFormRef.value.validate((valid) => {
    if (valid) {
      // if (roleForm.menuId.length === 0) {
      //   ElMessage.error('请至少选择一个权限');
      //   return;
      // }
      // 验证通过，调用保存接口

      if (props.rowData.id) {
        let opt = {
          role: {
            id: props.rowData.id,
            roleName: roleForm.roleName,
            description: roleForm.description
          },
          menuIds: roleForm.menuId,
          cockpitIds: roleForm.cockpitIds
        }

        saveRole(opt)
          .then((res) => {
            if (res.code === 200) {
              ElMessage.success("修改成功")
              handleClose()
              emit("saveBack", true)
            } else {
              ElMessage.success("修改失败")
            }
          })
          .catch(() => {
            ElMessage.error("角色修改失败，请稍后重试")
          })
      } else {
        let opt = {
          role: {
            roleName: roleForm.roleName,
            description: roleForm.description
          },
          menuIds: roleForm.menuId,
          cockpitIds: roleForm.cockpitIds
        }

        saveRole(opt)
          .then((res) => {
            if (res.code === 200) {
              ElMessage.success("新增成功")
              handleClose()
              emit("saveBack", true)
            } else {
              ElMessage.success("新增失败")
            }
          })
          .catch(() => {
            ElMessage.error("角色新增失败，请稍后重试")
          })
      }
    } else {
      return
    }
  })
}

function treeBackListWay(checkedKeys = []) {
  if (treeDialogType.value === "menu") {
    roleForm.menuId = checkedKeys?.length
      ? checkedKeys.map((ite) => {
          return ite.id
        })
      : []
    treeMenuCheckList.value = roleForm.menuId
    permissionsTags.value = checkedKeys?.length
      ? checkedKeys.map((ite) => {
          return ite.label
        })
      : []
  } else {
    roleForm.cockpitIds = checkedKeys?.length
      ? checkedKeys.map((ite) => {
          return ite.id
        })
      : []
    treeCockpitCheckList.value = roleForm.cockpitIds
    cockpitPermissions.value = checkedKeys?.length
      ? checkedKeys.map((ite) => {
          return ite.label
        })
      : []
  }
  treeDialogVisible.value = false
}

const handleClose = () => {
  roleForm.roleName = ""
  roleForm.description = ""
  roleForm.menuId = []
  roleForm.cockpitIds = []
  permissionsTags.value = []
  cockpitPermissions.value = []
  treeDialogType.value = ""
  treeMenuData.value = []
  treeMenuCheckList.value = []
  treeCockpitData.value = []
  treeCockpitCheckList.value = []
  emit("update:visible", false)
}

// 修改 getMenuByRoleIdFunc 函数，让它返回一个 Promise
function getMenuByRoleIdFunc(id) {
  return new Promise((resolve, reject) => {
    getMenuByRoleId({ roleId: id })
      .then((res) => {
        if (res.code === 200 && res.data) {
          roleForm.menuId = res.data.menuIds
          roleForm.cockpitIds = res.data.cockpitIds
          resolve()
        } else {
          roleForm.menuId = []
          roleForm.cockpitIds = []
          resolve()
        }
      })
      .catch((error) => {
        roleForm.menuId = []
        roleForm.cockpitIds = []
        reject(error)
      })
  })
}

// Only keep one declaration of handleOpen
async function handleOpen() {
  if (props.rowData.id) {
    roleForm.id = props.rowData.id
    roleForm.roleName = props.rowData.roleName
    roleForm.description = props.rowData.description
    roleForm.menuId = []
    roleForm.cockpitIds = []
    try {
      // Wait for getMenuByRoleIdFunc to complete
      await getMenuByRoleIdFunc(props.rowData.id)
      // Wait for getMenuListFunc to complete
    } catch (error) {
      console.error("Error loading menu data:", error)
      ElMessage.error("Error loading menu data, please try again later")
    }
  }

  getMenuListFunc()
  getCockpitFunc()
}

async function getMenuListFunc() {
  const { data } = await getMenuTreeList()
  treeMenuData.value = data
  if (!isEmpty(roleForm.menuId)) {
    treeMenuCheckList.value = roleForm.menuId
    permissionsTags.value = findLabels(treeMenuData.value, roleForm.menuId)
  }
}

async function getCockpitFunc() {
  const { data } = await getTree()
  treeCockpitData.value = data
  if (!isEmpty(roleForm.cockpitIds)) {
    treeCockpitCheckList.value = roleForm.cockpitIds
    cockpitPermissions.value = findLabels(data, roleForm.cockpitIds)
  }
}

// 根据id获取对应节点名称
function findLabels(tree, ids, field) {
  const result = []
  function findLabel(nodes) {
    for (const node of nodes) {
      if (ids.includes(node.id)) {
        result.push(node.label)
      }
      if (node.children && node.children.length) {
        findLabel(node.children)
      }
    }
  }

  findLabel(tree)
  return result
}
</script>

<style lang="scss" scoped>
.permissionList {
  width: 100%;
  height: auto;
  display: flex;
  flex-direction: column;
  .permissionList-item1 {
    width: 100%;
    display: flex;
    align-items: center;
    margin-bottom: 10px;
  }
  .permissionList-item2 {
    width: 100%;
    height: auto;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.zdy-divider {
  margin: 10px 0;
  border-color: #e9e9e9;
}
.dialog-footer {
  text-align: right;
  width: 100%;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

::v-deep .el-input-tag__inner {
  max-height: 100px;
  overflow: auto;
}
</style>
